home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpcsrc.lha
/
fpc
/
compiler
/
aopt386.inc
< prev
next >
Wrap
Text File
|
1998-09-24
|
55KB
|
1,315 lines
{
$Id: aopt386.inc,v 1.1.1.1 1998/03/25 11:18:12 root Exp $
Copyright (c) 1993-98 by Florian Klaempfl and Jonas Maebe
This include file contains the reloading optimizer for i386+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
{$Define OptimizeMovs}
Type TwoWords = Record
Word1, Word2: Word
End;
Function Reg32(Reg: TRegister): TRegister;
{Returns the 32 bit component of Reg if it exists, otherwise Reg is returned}
Begin
Reg32 := Reg;
If (Reg >= R_AX)
Then
If (Reg <= R_DI)
Then Reg32 := Reg16ToReg32(Reg)
Else
If (Reg <= R_BL)
Then Reg32 := Reg8toReg32(Reg);
End;
Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
Begin {checks whether Ref contains a reference to Reg}
Reg := Reg32(Reg);
RegInRef := (Ref.Base = Reg) Or (Ref.Index = Reg)
End;
Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
{checks if Reg is used by the instruction p1}
Var TmpResult: Boolean;
Begin
TmpResult := False;
If (Pai(p1)^.typ = ait_instruction) Then
Begin
Case Pai386(p1)^.op1t Of
Top_Reg: TmpResult := Reg = TRegister(Pai386(p1)^.op1);
Top_Ref: TmpResult := RegInRef(Reg, TReference(Pai386(p1)^.op1^))
End;
If Not(TmpResult) Then
Case Pai386(p1)^.op2t Of
Top_Reg:
if Pai386(p1)^.op3t<>Top_reg
then TmpResult := Reg = TRegister(Pai386(p1)^.op2)
else TmpResult := longint(Reg) = twowords(Pai386(p1)^.op2).word1;
Top_Ref: TmpResult := RegInRef(Reg, TReference(Pai386(p1)^.op2^))
End;
If Not(TmpResult) Then
Case Pai386(p1)^.op3t Of
Top_Reg: TmpResult := longint(Reg) =twowords(Pai386(p1)^.op2).word2;
Top_none:;
else
internalerror($Da);
End
End;
RegInInstruction := TmpResult
End;
Procedure ReloadOpt(AsmL: PaasmOutput);
Const MaxCh = 3;
{content types}
con_Unknown = 0;
con_ref = 1;
con_const = 2;
con_symbol = 3;
Type TChange = (C_None,
C_EAX, C_ECX, C_EDX, C_EBX, C_ESP, C_EBP, C_ESI, C_EDI,
{ C_AX, C_CX, C_DX, C_BX, C_SP, C_BP, C_SI, C_DI,
C_AL, C_CL, C_DL, C_BL,
C_AH, C_CH, C_BH, C_DH,
C_DEFAULT_SEG, C_CS, C_DS, C_ES, C_FS, C_GS, C_SS,
} C_Flags, C_FPU,
C_Op1, C_Op2, C_Op3,
C_MemEDI);
TAsmInstrucProp = Record
NCh: Byte;
Ch: Array[1..MaxCh] of TChange;
End;
TContent = Record
StartMod: Pointer; {start and end of block instructions that defines the
content of this register; If Typ = con_const, then
Longint(StartMod) = value of the constant)}
State: Word; {starts at 0, gets increased everytime the register is modified}
NrOfMods: Byte;
{ ModReg: TRegister; }{if one register gets a block assigned from an other register,
this variable holds the name of that register (so it can be
substituted when checking the block afterwards)}
Typ: Byte; {con_*}
{ CanBeDestroyed: Boolean;} {if it's a register modified by the optimizer}
End;
TRegContent = Array[R_NO..R_EDI] Of TContent;
TRegFPUContent = Array[R_ST..R_ST7] Of TContent;
TPaiProp = Record
Regs: TRegContent;
{ FPURegs: TRegFPUContent;} {currently not yet used}
LineSave: Longint;
{can this instruction be removed?}
CanBeRemoved: Boolean;
End;
PPaiProp = ^TPaiProp;
{$IfDef TP}
TPaiPropBlock = Array[1..(65520 div (((SizeOf(TPaiProp)+1)div 2)*2))] Of TPaiProp;
{$else}
TPaiPropBlock = Array[1..250000] Of TPaiProp;
{$EndIf TP}
PPaiPropBlock = ^TPaiPropBlock;
Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
{MOV} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
{MOVZX} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
{MOVSX} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
{LABEL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
{ADD} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{CALL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
{IDIV} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
{IMUL} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)), {handled separately, because several forms exist}
{JMP} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
{LEA} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
{MUL} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
{NEG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{NOT} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
{POP} (NCh: 2; Ch: (C_Op1, C_ESP, C_None)),
{POPAD} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
{PUSH} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
{PUSHAD} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
{RET} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
{SUB} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{XCHG} (NCh: 2; Ch: (C_Op1, C_Op2, C_None)), {(will be) handled seperately}
{XOR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{FILD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{CMP} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
{JZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
{INC} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
{DEC} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
{SETE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{SETNE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{SETL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{SETG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{SETLE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{SETGE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{JE} (NCh: 0; Ch: (C_None, C_None, C_None)),
{JNE} (NCh: 0; Ch: (C_None, C_None, C_None)),
{JL} (NCh: 0; Ch: (C_None, C_None, C_None)),
{JG} (NCh: 0; Ch: (C_None, C_None, C_None)),
{JLE} (NCh: 0; Ch: (C_None, C_None, C_None)),
{JGE} (NCh: 0; Ch: (C_None, C_None, C_None)),
{OR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{FLD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FADD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FMUL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FSUB} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FDIV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FCHS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FLD1} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{FIDIV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
{CLTD} (NCh: 1; Ch: (C_EDX, C_None, C_None)),
{JNZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
{FSTP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
{AND} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{JNO} (NCh: 0; Ch: (C_None, C_None, C_None)),
{NOTH} (NCh: 0; Ch: (C_None, C_None, C_None)), {***???***}
{NONE} (NCh: 0; Ch: (C_None, C_None, C_None)),
{ENTER} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
{LEAVE} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
{CLD} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
{MOVS} (NCh: 3; Ch: (C_ESI, C_EDI, C_MemEDI)),
{REP} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
{SHL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{SHR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
{BOUND} (NCh: 0; Ch: (C_None, C_None, C_None)),